home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
kcl.lha
/
ustation
/
ild.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-01-17
|
4KB
|
204 lines
#include <stdio.h>
#include <a.out.h>
#define POOLSIZ 100000
#define MY_SYMTABSIZ 10000
#define SYMTABSIZ 10000
struct Nlist {
char *N_name;
int N_type;
int N_value;
};
char pool[POOLSIZ+128];
char *pp = pool;
struct bhdr my_header;
struct Nlist my_Symtab[MY_SYMTABSIZ];
int my_Sx;
struct bhdr header;
char *text, *data, *bss;
char *rtext, *rdata, *rbss;
struct Nlist Symtab[SYMTABSIZ];
int Sx;
struct reloc rinfo;
main(argc, argv)
int argc;
char **argv;
{
if (argc < 5) {
fprintf(stderr, "Arg count.\n");
exit(1);
}
get_myself(argv[1]);
rtext = (char *)atoi(argv[2]);
fasload(argv[3], argv[4]);
}
get_myself(filename)
char *filename;
{
struct sym sym;
int i;
FILE *fp;
extern char *malloc();
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Can't open %s.\n", filename);
exit(1);
}
fread(&my_header, sizeof(struct bhdr), 1, fp);
if (my_header.fmagic != FMAGIC && my_header.fmagic != NMAGIC) {
fprintf(stderr, "Illegal magic number: 0%o.\n", my_header.fmagic);
exit(1);
}
fseek(fp, my_header.tsize+my_header.dsize, 1);
for (my_Sx=0, i=0; i<my_header.ssize-sizeof(struct sym); my_Sx++) {
if (my_Sx >= MY_SYMTABSIZ) {
fprintf(stderr, "Too many symbols in %s.\n", filename);
exit(1);
}
if (pp >= &pool[POOLSIZ]) {
fprintf(stderr, "String table overflow.\n");
exit(1);
}
fread(&sym, 1, sizeof(struct sym), fp);
i += sizeof(struct sym);
my_Symtab[my_Sx].N_name = pp;
my_Symtab[my_Sx].N_type = sym.stype;
my_Symtab[my_Sx].N_value = sym.svalue;
while ((*pp = getc(fp)) != '\0') {
pp++;
i++;
}
pp++;
i++;
}
fclose(fp);
}
fasload(filename, outputfilename)
char *filename, *outputfilename;
{
struct sym sym;
int i, n;
char name[100], *p;
int type, value;
int msx;
FILE *fp;
extern char *malloc();
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Can't open %s.\n", filename);
exit(1);
}
fread(&header, sizeof(struct bhdr), 1, fp);
if (header.fmagic != FMAGIC) {
fprintf(stderr, "Illegal magic number: 0%o.\n", header.fmagic);
exit(1);
}
text = malloc(header.tsize+header.dsize);
data = text + header.tsize;
bss = data + header.dsize;
rdata = rtext + header.tsize;
rbss = rdata + header.dsize;
fread(text, 1, header.tsize+header.dsize, fp);
for (Sx=0, i=0; i<header.ssize-sizeof(struct sym); Sx++) {
if (Sx >= SYMTABSIZ) {
fprintf(stderr, "Too many symbols in %s.\n", filename);
exit(1);
}
fread(&sym, 1, sizeof(struct sym), fp);
i += sizeof(struct sym);
Symtab[Sx].N_type = type = sym.stype;
Symtab[Sx].N_value = value = sym.svalue;
p = name;
while ((*p++ = getc(fp)) != '\0')
i++;
i++;
if ((type & N_EXT) == 0 || (type & N_TYPE) != N_UNDF)
continue;
for (msx = 0; msx < my_Sx; msx++) {
if ((my_Symtab[msx].N_type & N_EXT) == 0)
continue;
if (strcmp(my_Symtab[msx].N_name, name) == 0) {
Symtab[Sx].N_value = my_Symtab[msx].N_value;
goto CONTINUE;
}
}
/*
if (value == 0)
*/
fprintf(stderr, "Undefined symbol: %s.\n", name);
/*
Symtab[Sx].N_value = (int)(rtext + header.bsize);
header.bsize += value;
*/
CONTINUE:
;
}
fseek(fp, sizeof(struct bhdr)+header.tsize+header.dsize+header.ssize, 0);
for (i = 0, n = header.rtsize / sizeof(struct reloc);
i < n; i++) {
fread(&rinfo, sizeof(struct reloc), 1, fp);
relocate(text);
}
for (i = 0, n = header.rdsize / sizeof(struct reloc);
i < n; i++) {
fread(&rinfo, sizeof(struct reloc), 1, fp);
relocate(data);
}
fclose(fp);
fp = fopen(outputfilename, "w");
if (fp == NULL) {
fprintf(stderr, "Can't open %s.\n", outputfilename);
exit(1);
}
fwrite(&header, sizeof(struct bhdr), 1, fp);
fwrite(text, 1, header.tsize+header.dsize, fp);
fclose(fp);
}
relocate(where)
char *where;
{
int value;
where += rinfo.rpos;
switch (rinfo.rsegment) {
case RTEXT:
value = (int)rtext;
break;
case RDATA:
value = (int)rtext;
break;
case RBSS:
value = (int)rtext;
break;
case REXT:
value = Symtab[rinfo.rsymbol].N_value;
break;
}
switch (rinfo.rsize) {
case RBYTE:
*(char *)where += value;
break;
case RWORD:
*(short *)where += value;
break;
case RLONG:
*(int *)where += value;
break;
}
}